package impl.game;

import framework.*;
import org.apache.log4j.Logger;

import java.util.Arrays;

/**
 * Date: 27.03.2008
 * Time: 23:14:48
 *
 * @author Denis DIR Rozhnev
 */
public class Every2every extends AbstractGame {
    private static final Logger LOG = Logger.getLogger(Every2every.class);
    private static final boolean VERBOSE = false;
    private int[][] turnLog;


    @Override
    public void init(Person[] persons, Business business) {
        super.init(persons, business);
        int c = persons.length;
        if (VERBOSE)
            turnLog = new int[c][c];
        turnNumber = 0;
        for (Person person : persons) {
            person.init(new Context(person));
        }
    }

    @Override
    public void turn(int count) throws DeepException {
        if (peers.length == 0) throw new DeepException("Every2every game is not initialized");
        StringBuffer buff = new StringBuffer(128);

        for (int n = turnNumber + count; turnNumber < n; turnNumber++) {
            buff.append("i").append(turnNumber).append(':');
            logClear();
            for (int i = 0; i < peers.length - 1; i++) {
                Person p1 = peers[i];
                for (int j = i + 1; j < peers.length; j++) {
                    Person p2 = peers[j];
                    int[] res = biz.doBusiness(p1, p2);
                    addScore(i, res[0]);
                    addScore(j, res[1]);
                    logAdd(i, j, res);
                }
            }

            for (int res : getScores()) {
                buff.append(" ").append(res);
            }
            LOG.debug(buff.toString());
            buff.setLength(0);
            logPost();
        }
    }

    private void logPost() {
        if (VERBOSE) {
            StringBuilder b = new StringBuilder(128);
            for (int i = 0; i < turnLog.length; i++) {
                int[] ints = turnLog[i];
                b.append(peers[i].getClass().getName()).append(":\t");
                int s = 0;
                for (int anInt : ints) {
                    b.append(anInt).append(' ');
                    s += anInt;
                }
                b.append(": ").append(s).append(": ").append(getScores()[i]);
                LOG.debug(b.toString());
                b.setLength(0);
            }
        }
    }

    private void logClear() {
        if (VERBOSE)
            for (int[] ints : turnLog) {
                Arrays.fill(ints, 0);
            }
    }

    private void logAdd(int i, int j, int[] res) {
        if (VERBOSE) {
            turnLog[i][j] = res[0];
            turnLog[j][i] = res[1];
        }
    }


    private class Context implements PersonContext {
        protected Object personId;

        public Context(Object personId) {
            this.personId = personId;
        }

        @Override
        public Object sendMessage(Object id, Object message) {
            return ((Person) id).messageReceived(personId, message);
        }
    }
}
